﻿#include "stuinfomntwiget.h"
#include "ui_stuinfomntwiget.h"
#include <QMessageBox>
#include <QDebug>
StuInfoMntWiget::StuInfoMntWiget(QWidget *parent) :
    QWidget(parent),
    sim_ui(new Ui::StuInfoMntWiget)
{
    sim_ui->setupUi(this);

    // 要添加学生信息
    qRegisterMetaType<CStuInfo>("CStuInfo");
    qRegisterMetaType<CStuInfo>("CStuInfo&");

    // 数据源
    dataSource = new CDataMySQL;
    //  dataSource = new CDataJion; 可选 待补充

    // tableview行元素初始化
    dataItemModel = new QStandardItemModel(this); // 添加这行初始化

    // 添加学生信息窗口
    addStuWin = new DialAddStuInfo(this);
    ordId = 0;
    connect(addStuWin,&DialAddStuInfo::sig_addInfo,this,&StuInfoMntWiget::slot_addInfo);

    // 修改学生信息
    connect(addStuWin,&DialAddStuInfo::sig_modInfo,this,&StuInfoMntWiget::slot_modInfo);

    // 菜单
    menu = new QMenu(this);
    actUpdate = new QAction("修改学生信息",menu);
    actDelete = new QAction("删除学生信息",menu);
    menu->addAction(actUpdate);     // 添加菜单项
    menu->addAction(actDelete);
    sim_ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
    // 在tableview的item上面右键，弹出菜单
    connect(sim_ui->tableView,&QTableView::customContextMenuRequested,this,&StuInfoMntWiget::slot_popMenu);
    connect(actUpdate,&QAction::triggered,this,&StuInfoMntWiget::slot_actUpdate);
    connect(actDelete,&QAction::triggered,this,&StuInfoMntWiget::slot_actDelete);

    // 全选item槽函数
    connect(dataItemModel,&QStandardItemModel::itemChanged,this,&StuInfoMntWiget::slot_itemChecked);

    // 初始化UI
    initUI();
}

StuInfoMntWiget::~StuInfoMntWiget()
{
    // --------------------------------------------------------------------------------- 学生信息 表结构改变 需改的代码
    delete dataSource;
    delete sim_ui;
}


bool StuInfoMntWiget::addToTableView(CStuInfo &stuInfo)
{
    // 为每一行数据创建新的QStandardItem对象
    QStandardItem *itemId = new QStandardItem(QString("%1").arg(stuInfo.getId(), 6, 10, QLatin1Char('0')));     // 10进制 不够6位 不愁到6位
    QStandardItem *itemName = new QStandardItem;
    QStandardItem *itemGender = new QStandardItem;
    QStandardItem *itemPolitID = new QStandardItem;
    QStandardItem *itemPhoneNum = new QStandardItem;
    QStandardItem *itemAddress = new QStandardItem;
    QStandardItem *itemGpa = new QStandardItem;

    itemId->setCheckable(true);                                 // 复选框
    itemName->setData(stuInfo.getName(), Qt::DisplayRole);
    itemGender->setData(stuInfo.getGender(), Qt::DisplayRole);
    itemPolitID->setData(stuInfo.getPolitId(), Qt::DisplayRole);
    itemPhoneNum->setData(stuInfo.getPhoneNum(), Qt::DisplayRole);
    itemAddress->setData(stuInfo.getAddress(), Qt::DisplayRole);
    itemGpa->setData(stuInfo.getGpa(), Qt::DisplayRole);

    QList<QStandardItem*> rowItem;
    rowItem.append(itemId);
    rowItem.append(itemName);
    rowItem.append(itemGender);
    rowItem.append(itemPolitID);
    rowItem.append(itemPhoneNum);
    rowItem.append(itemAddress);
    rowItem.append(itemGpa);

    for(int i = 0; i < rowItem.size(); ++i) {
        rowItem[i]->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);  // 居中显示
    }

    dataItemModel->appendRow(rowItem);
    return true;
}

void StuInfoMntWiget::initUI()
{
    // 查询数据
    QList<CStuInfo> stuInfoList;
    if(!dataSource->selectStuInfo(stuInfoList)){
        QMessageBox::critical(this,tr("错误"),tr("从数据库查询学生信息失败"));
        return;
    }
    // tableview显示数据
    sim_ui->tableView->setModel(dataItemModel);
    // 每条数据添加到tableview
    for (int i=0;i<stuInfoList.size();++i) {
        addToTableView(stuInfoList[i]);
    }
    // 添加表头
    QStringList headerList;
    // --------------------------------------------------------------------------------- 学生信息 表结构改变 需改的代码
    headerList<<"学号"<<"姓名"<<"性别"<<"政治身份"<<"手机号"<<"住址"<<"绩点";
    dataItemModel->setHorizontalHeaderLabels(headerList);
//    sim_ui->tableView->verticalHeader()->setVisible(false); // 隐藏序列号
    // 每行的数据不能编辑
    sim_ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    // 设置列宽
//    for(int col=0;col<CONST_TABLE_COLSIZE;++col){
//        int colWidth = sim_ui->tableView->geometry().width()/4;
//        sim_ui->tableView->setColumnWidth(col,colWidth);
//    }
}



// 返回登录去登录
void StuInfoMntWiget::on_btnBack2Log_clicked()
{
    emit this->backToLog();
}

// 添加学生信息
void StuInfoMntWiget::slot_addInfo(CStuInfo &stuInfo)
{
    // 添加信息到数据库
    if(!dataSource->addStuInfo(stuInfo)){
        QMessageBox::critical(this,tr("错误"),tr("向数据库添加学生信息失败\n"
                                               "学号或者手机号重复"));
        return;
    }
    // 添加信息到显示
    addToTableView(stuInfo);
    // 弹窗提示添加成功
    QMessageBox::information(this,tr("提示"),tr("学生信息添加成功"));
}

// 修改学生信息   // TODO 解决修改了信息后，多了一行新信息的问题
void StuInfoMntWiget::slot_modInfo(CStuInfo &stuInfo)
{
    // 修改数据库的信息
    if(!dataSource->updateStuInfo(stuInfo,ordId)){
        QMessageBox::critical(this,tr("错误"),tr("向数据库修改学生信息失败"));
        return;
    }
    // 添加信息到显示
    int row = sim_ui->tableView->currentIndex().row();  // 获取当前行
    dataItemModel->setData(dataItemModel->item(row,CONST_ID_COL)->index(),stuInfo.getId());    // 设置该行的每个字段为修改后的值
    dataItemModel->setData(dataItemModel->item(row,CONST_NAME_COL)->index(),stuInfo.getName());
    dataItemModel->setData(dataItemModel->item(row,CONST_GENDER_COL)->index(),stuInfo.getGender());
    dataItemModel->setData(dataItemModel->item(row,CONST_POLID_COL)->index(),stuInfo.getPolitId());
    dataItemModel->setData(dataItemModel->item(row,CONST_PHONUM_COL)->index(),stuInfo.getPhoneNum());
    dataItemModel->setData(dataItemModel->item(row,CONST_ADDRESS_COL)->index(),stuInfo.getAddress());
    dataItemModel->setData(dataItemModel->item(row,CONST_GPA_COL)->index(),stuInfo.getGpa());

    // 弹窗提示添加成功
    QMessageBox::information(this,tr("提示"),tr("学生信息修改成功"));
}

// 添加学生信息
void StuInfoMntWiget::on_btnAddData_clicked()
{
    addStuWin->on_btnClearAll_clicked();
    addStuWin->setWindowTitle("添加学生信息");
    addStuWin->setAddBtnText("添加学生");
    addStuWin->setIsModOrAdd(false);
    addStuWin->exec();
}

// 全选学生信息
void StuInfoMntWiget::on_chkBox_selectAll_clicked(bool checked)
{
    for(int row=0;row<dataItemModel->rowCount();++row){
        if(checked)
            dataItemModel->item(row)->setCheckState(Qt::Checked);
        else
            dataItemModel->item(row)->setCheckState(Qt::Unchecked);
    }
}

bool StuInfoMntWiget::slot_itemChecked(QStandardItem *item)
{
    // 只有勾选第一个item才有效
    if(dataItemModel->indexFromItem(item).column()>0)
        return false;
    // 如果tableview中有一个item没有被勾选，全选取消
    for(int row=0;row<dataItemModel->rowCount();++row){
        if(dataItemModel->item(row)->checkState() != Qt::Checked){
            sim_ui->chkBox_selectAll->setChecked(false);
            return false;
        }
    }
    // 当全部item都被勾选，全选打勾
    sim_ui->chkBox_selectAll->setChecked(true);
    return true;
}

// 弹出菜单栏
bool StuInfoMntWiget::slot_popMenu(const QPoint &pos)
{
    // 在tableview的item上面右键，弹出菜单
    if(dataItemModel->itemFromIndex(sim_ui->tableView->indexAt(pos)) != nullptr)
        menu->exec(QCursor::pos());
    return true;
}

// 菜单栏——修改信息
bool StuInfoMntWiget::slot_actUpdate()
{
    addStuWin->setWindowTitle("修改学生信息");
    addStuWin->setAddBtnText("修改信息");
    addStuWin->setIsModOrAdd(true);
    // 获取当前item的学生信息
    int row = sim_ui->tableView->currentIndex().row();
    ordId = dataItemModel->item(row,CONST_ID_COL)->text().toInt();
    QString name = dataItemModel->item(row,CONST_NAME_COL)->text();
    QString gender = dataItemModel->item(row,CONST_GENDER_COL)->text();
    QString polId = dataItemModel->item(row,CONST_POLID_COL)->text();
    QString phoNum = dataItemModel->item(row,CONST_PHONUM_COL)->text();
    QString address = dataItemModel->item(row,CONST_ADDRESS_COL)->text();
    float gpa = dataItemModel->item(row,CONST_GPA_COL)->text().toFloat();
    // 显示学生信息
    addStuWin->showItemInfo(ordId,name,gender,polId,phoNum,address,gpa);
    addStuWin->exec();
    return true;
}

// 菜单栏——删除信息
bool StuInfoMntWiget::slot_actDelete()
{
    // 删除前进行提示，是否决定删除数据
    int ret = QMessageBox::question(this, tr("提示"),
                                   tr("确定删除选中的学生信息吗？"),
                                   QMessageBox::Yes | QMessageBox::No);

    // 如果用户选择取消，直接返回
    if(ret == QMessageBox::No) return false;
    // 根据该行的ID删除学生信息
    int row = sim_ui->tableView->currentIndex().row();
    int id = dataItemModel->item(row)->text().toInt();
    if(!dataSource->deleteStuInfo(id)){
        QMessageBox::critical(this,tr("错误"),tr("从数据库删除学生信息失败"));
        return false;
    }
    dataItemModel->removeRow(row);
    return true;
}

// 删除学生信息
void StuInfoMntWiget::on_btnDelData_clicked()
{
    // 获取要删除的行item
    QMap<int,QStandardItem*> delRowsMap;
    for(int row=0;row<dataItemModel->rowCount();++row){
        QStandardItem* item = dataItemModel->item(row);
        if(item && item->checkState() == Qt::Checked){
            delRowsMap.insert(row,item);        // 获取item 和 item所在行
        }
    }

    // 没有勾选 弹窗提示，且不删除
    if(delRowsMap.size()<1){
        QMessageBox::information(this,tr("提示"),tr("当前没有勾选数据，无法删除"));
        return;
    }

    // 删除前进行提示，是否决定删除数据
    int ret = QMessageBox::question(this, tr("提示"),
                                   tr("确定删除选中的学生信息吗？"),
                                   QMessageBox::Yes | QMessageBox::No);

    // 如果用户选择取消，直接返回
    if(ret == QMessageBox::No) return;

    // 用户确认删除，执行删除操作
    // 1.删除数据库中的数据
    // 根据id来删除数据
    // 而且需要从后往前删除
    QList<int> keyList = delRowsMap.keys();
    for(int key=keyList.size()-1;key>=0;--key){
        if(!dataSource->deleteStuInfo(delRowsMap.value(keyList[key])->text().toInt())){
            QMessageBox::critical(this,tr("错误"),tr("从数据库删除学生信息失败"));
            return;
        }
        // 2.删除窗口中的数据
        dataItemModel->removeRow(keyList[key]);
    }
}
